/** @odoo-module */
import * as spreadsheet from "@odoo/o-spreadsheet";
import { SpreadsheetComponent } from "@spreadsheet_edition/bundle/actions/spreadsheet_component";
// import { useSetupAction } from "@web/webclient/actions/action_hook";
import { _t } from "@web/core/l10n/translation";
import { patch } from "@web/core/utils/patch";

const { Model } = spreadsheet;
const { useSubEnv } = owl;

patch(SpreadsheetComponent.prototype, {
    setup() {
        this._super();
        useSubEnv({
            saveToFiles: this.SaveToFiles.bind(this),
            convertToRecords: this.ConvertToRecords.bind(this)
        });
    },

    /**
     * Save spreadsheet to file.
     */
    async SaveToFiles() {
        debugger
        const child = await this.props.onWhichSpreadsheet();
        if (child == "template") {
            const data = this.model.exportData();
            let data_json = JSON.stringify(data);
            this.props.onSaveToFiles(data_json);
        }
    },

    /**
     * Spreadsheet convert to record.
     */
    async ConvertToRecords() {
        const child = await this.props.onWhichSpreadsheet();
        if (child == "datum") {
            const data = this.model.exportData();
            const model = new Model(data, { dataSources: this.model.config.dataSources });
            await waitForDataLoaded(model);
            console.log('wait ----------------------- done');
            let cell_map = {};
            let sheet_id = model.getters.getSheetIds()[0];
            for (const cell of Object.values(model.getters.getCells(sheet_id))) {
                const { col, row } = model.getters.getCellPosition(cell.id);
                let line = cell_map[row];
                if (line === undefined) {
                    line = {};
                    cell_map[row] = line;
                }
                let value = cell.isFormula ? cell.evaluated.value : cell.content.value;
                line[col] = value;
            }
            console.log("for --------------------done ");
            let cells_json = JSON.stringify(cell_map);
            this.props.onConvertToRecords(cells_json);
        }
    }
});

Object.assign(SpreadsheetComponent.props, {
    onSaveToFiles: {
        type: Function,
        optional: true
    },
    onConvertToRecords: {
        type: Function,
        optional: true
    },
    onWhichSpreadsheet: {
        type: Function,
        optional: true
    }
});

/**
     * Ensure that the spreadsheet does not contains cells that are in loading state
     * @param {Model} model
     * @returns {Promise<void>}
     */
async function waitForDataLoaded(model) {
    const dataSources = model.config.dataSources;
    return new Promise((resolve, reject) => {
        function check() {
            model.dispatch("EVALUATE_CELLS");
            if (isLoaded(model)) {
                dataSources.removeEventListener("data-source-updated", check);
                resolve();
            }
        }
        dataSources.addEventListener("data-source-updated", check);
        check();
    });
}

function isLoaded(model) {
    for (const sheetId of model.getters.getSheetIds()) {
        for (const cell of Object.values(model.getters.getCells(sheetId))) {
            if (
                cell.evaluated &&
                cell.evaluated.type === "error" &&
                cell.evaluated.error.message === _t("Data is loading")
            ) {
                return false;
            }
        }
    }
    return true;
}
